/*
** Copyright (C) 2009 Joshua Brent Marsh <joshua@icub3d.com>
**  
** This file is part of icub3d-adt
**
** icub3d-adt is free sofware; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**  
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**  
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**  
*/

/* $Id: list.h 53 2009-12-24 20:43:05Z joshua@icub3d.com $ */

#ifndef ICUB3D_LIST_H
#define ICUB3D_LIST_H 1

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>

#include "function_prototypes.h"

/* The type of lists we can have. */
typedef
enum list_type
  {
    DOUBLEY_LINKED,
    CIRCULAR_DOUBLEY_LINKED
  } ListType;

/* The structure for each node in the list. */
typedef
struct list_node 
{
  struct list_node *prev; /* The previous item in the list. Could be NULL. */
  struct list_node *next; /* The next item in the list. Could be NULL. */
  const void * item;      /* The item in this position of the list. */
} ListNode;

/* This is the main structure that will be passed between the functions. */
typedef
struct list {
  ListType type;          /* The type of the list we are using. */
  ListNode *head;         /* The first element in the list. */
  ListNode *tail;         /* The last element in the list. */
  size_t size;            /* The size of the list. */
} List;

/* A Traverser for lists. Should perform faster on average than simple for
   loops using list_get. */
typedef
struct list_traverser {
  const List *list;
  ListNode *cur;
  int last_call;
} ListTraverser;

/* Helper functions that other ADTs may use. */
void * list_remove_helper (List *list, ListNode *cur);
int list_insert_helper (List *list, ListNode *node, const void *item,
			const int after);

/* Creation and copy functions. */
List * list_create ();
List * list_create_circular ();
List * list_copy (const List *src, copy_func *cfunc, destroy_func *dfunc);

/* Cleaup functions. */
void list_destroy (List *list, destroy_func *func);

/* Basic list functionality. */
#define list_size(list) ((list)->size)
void * list_get (const List *list, const size_t pos);
void * list_remove (List *list, const size_t pos);
int list_insert (List *list, const size_t pos, const void *item);

/* Some defined helpers for the basic functionality. */
#define list_remove_first(list)       (list_remove_helper (list, list->head))
#define list_remove_last(list)        (list_remove_helper (list, list->tail))
#define list_get_first(list)          (list_get (list, 0))
#define list_get_last(list)           (list_get (list, list_size (list)-1))
#define list_insert_first(list, item) (list_insert_helper (list, list->head, \
							   item, 0))
#define list_insert_last(list, item)  (list_insert_helper (list, list->tail, \
							   item, 1))


/* Basic traverser functionality. */
void list_traverser_init (ListTraverser *trav, const List *list);
void * list_traverser_next (ListTraverser *trav);
void * list_traverser_prev (ListTraverser *trav);
void * list_traverser_cur (ListTraverser *trav);
void * list_traverser_remove (ListTraverser *trav);
int list_traverser_insert_before (ListTraverser *trav, const void *item);
int list_traverser_insert_after (ListTraverser *trav, const void *item);
void * list_traverser_first (ListTraverser *trav);
void * list_traverser_last (ListTraverser *trav);

#endif /* ICUB3D_LIST_H */
